package com.dudy.authdemo.service.impl;

import com.dudy.common.base.BaseService;
import com.dudy.common.base.PageData;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.common.Mapper;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: auth_demo
 * @author: dudy
 * @create: 2020-12-24 09:51
 * @description:
 **/
@Transactional(rollbackFor = Exception.class)
public abstract class BaseServiceImpl<T , V extends PageData> implements BaseService<T, V> {

    @Autowired
    protected Mapper<T> mapper;

    public Mapper<T> getMapper() {
        return mapper;
    }

    @Override
    public int deleteByPrimaryKey(Object id) throws Exception {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteByExample(Object example) throws Exception {
        return mapper.deleteByExample(example);
    }

    @Override
    public int insert(T record) throws Exception {
        return mapper.insert(record);
    }

    @Override
    public int insertSelective(T record) throws Exception {
        return mapper.insertSelective(record);
    }

    @Override
    public V selectByPrimaryKey(Object id) throws Exception {
        T t = mapper.selectByPrimaryKey(id);
        V v = create();
        if (t != null) {
            BeanUtils.copyProperties(t, v);
        }
        return v;
    }

    @Override
    public List<V> selectByExample(Object example) throws Exception {
        List<T> ts = mapper.selectByExample(example);
        if (CollectionUtils.isEmpty(ts)) {
            return new ArrayList<>();
        }
        List<V> list = new ArrayList<>(ts.size());
        ts.forEach(t -> {
            V v = create();
            BeanUtils.copyProperties(t, v);
            list.add(v);
        });
        return list;
    }

    @Override
    public int countByExample(Object example) throws Exception {
        return mapper.selectCountByExample(example);
    }

    @Override
    public List<V> selectAll() throws Exception {
        List<T> ts = mapper.selectAll();
        if (CollectionUtils.isEmpty(ts)) {
            return new ArrayList<>();
        }
        List<V> list = new ArrayList<>(ts.size());
        ts.forEach(t -> {
            V v = create();
            BeanUtils.copyProperties(t, v);
            list.add(v);
        });
        return list;
    }

    @Override
    public V selectOne(T record) throws Exception {
        T t = mapper.selectOne(record);
        if (t == null) {
            return null;
        }
        V v = create();
        BeanUtils.copyProperties(t, v);
        return v;
    }

    @Override
    public V selectOneByExample(Object example) throws Exception {
        T t = mapper.selectOneByExample(example);
        if (t == null) {
            return null;
        }
        V v = create();
        BeanUtils.copyProperties(t, v);
        return v;
    }

    @Override
    public int updateByPrimaryKey(T record) throws Exception {
        T t = mapper.selectByPrimaryKey(record);
        if (t == null) {
            return 0;
        }
        BeanUtils.copyProperties(record, t);
        return mapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByExampleSelective(T record, Object example) throws Exception {
        return mapper.updateByExampleSelective(record, example);
    }

    @Override
    public PageData<V> selectPageByExample(V v, Object example) throws Exception {
        PageHelper.startPage(v.getPageNum(), v.getPageSize());
        PageInfo<T> pageInfo = new PageInfo<>(mapper.selectByExample(example));
        if (CollectionUtils.isEmpty(pageInfo.getList())) {
            return new PageData<>();
        }
        ArrayList<V> vs = new ArrayList<V>((int)pageInfo.getTotal());
        pageInfo.getList().forEach((T t) -> {
            V v1 = create();
            BeanUtils.copyProperties(t, v1);
            vs.add(v1);
        });
        PageData<V> pageData = new PageData<>();
        BeanUtils.copyProperties(pageInfo,pageData);
        pageData.setList(vs);
        return pageData;
    }

    @Override
    public abstract V create();

}
